#include "remoteclient.h"
#include <QBuffer>
#ifdef EREMOTEPROTOCOL_QDEBUG
#include <QDebug>
#endif

RemoteClient::RemoteClient(QObject *parent) : RemoteTcpSocket(parent)
{
}

RemoteClient::~RemoteClient()
{

}

bool RemoteClient::sendKey(int wid, int key, bool isPress)
{
    int size = 0;
    Client2ServerMessageType mt = Client2ServerMessageType::C2S_KeyEvent;
    size = sizeof(mt) + sizeof(wid) + sizeof(key) + sizeof(isPress);

    this->mustWrite(static_cast<const char*>(static_cast<const void *>(&size)), sizeof(size));
    this->mustWrite(static_cast<const char*>(static_cast<const void *>(&mt)), sizeof(mt));
    this->mustWrite(static_cast<const char*>(static_cast<const void *>(&wid)), sizeof(wid));
    this->mustWrite(static_cast<const char*>(static_cast<const void *>(&key)), sizeof(key));
    return this->mustWrite(static_cast<const char*>(static_cast<const void *>(&isPress)), sizeof(isPress));
}

bool RemoteClient::sendMouse(int wid, int button, bool isPress, int x, int y)
{
    int size = 0;
    Client2ServerMessageType mt = Client2ServerMessageType::C2S_MouseEvent;
    size = sizeof(mt) + sizeof(wid) + sizeof(button)+ sizeof(isPress)+ sizeof(x)+ sizeof(y);

    this->mustWrite(static_cast<const char*>(static_cast<const void *>(&size)), sizeof(size));
    this->mustWrite(static_cast<const char*>(static_cast<const void *>(&mt)), sizeof(mt));
    this->mustWrite(static_cast<const char*>(static_cast<const void *>(&wid)), sizeof(wid));
    this->mustWrite(static_cast<const char*>(static_cast<const void *>(&button)), sizeof(button));
    this->mustWrite(static_cast<const char*>(static_cast<const void *>(&isPress)), sizeof(isPress));
    this->mustWrite(static_cast<const char*>(static_cast<const void *>(&x)), sizeof(x));
    return this->mustWrite(static_cast<const char*>(static_cast<const void *>(&y)), sizeof(y));
}

bool RemoteClient::sendWheel(int wid, int delta)
{
    int size = 0;
    Client2ServerMessageType mt = Client2ServerMessageType::C2S_WheelEvent;
    size = sizeof(mt) + sizeof(wid) + sizeof(delta);
    this->mustWrite(static_cast<const char*>(static_cast<const void *>(&size)), sizeof(size));
    this->mustWrite(static_cast<const char*>(static_cast<const void *>(&mt)), sizeof(mt));
    this->mustWrite(static_cast<const char*>(static_cast<const void *>(&wid)), sizeof(wid));
    return this->mustWrite(static_cast<const char*>(static_cast<const void *>(&delta)), sizeof(delta));
}

bool RemoteClient::sendStartCap(int wid)
{
    int size = 0;
    Client2ServerMessageType mt = Client2ServerMessageType::C2S_StartCap;
    size = sizeof(mt) + sizeof(wid);
    this->mustWrite(static_cast<const char*>(static_cast<const void *>(&size)), sizeof(size));
    this->mustWrite(static_cast<const char*>(static_cast<const void *>(&mt)), sizeof(mt));
    return this->mustWrite(static_cast<const char*>(static_cast<const void *>(&wid)), sizeof(wid));
}

bool RemoteClient::sendStopCap(int wid)
{
    int size = 0;
    Client2ServerMessageType mt = Client2ServerMessageType::C2S_PauseCap;
    size = sizeof(mt) + sizeof(wid);
    this->mustWrite(static_cast<const char*>(static_cast<const void *>(&size)), sizeof(size));
    this->mustWrite(static_cast<const char*>(static_cast<const void *>(&mt)), sizeof(mt));
    return this->mustWrite(static_cast<const char*>(static_cast<const void *>(&wid)), sizeof(wid));

}

bool RemoteClient::sendCutText(const QString &text)
{
    int size = 0;
    Client2ServerMessageType mt = Client2ServerMessageType::C2S_UpdateCutTextEvent;
    QByteArray utf8Buff = text.toUtf8();
    size = sizeof(mt) + utf8Buff.size();
    this->mustWrite(static_cast<const char*>(static_cast<const void *>(&size)), sizeof(size));
    this->mustWrite(static_cast<const char*>(static_cast<const void *>(&mt)), sizeof(mt));
    return this->mustWrite(utf8Buff);
}

void RemoteClient::parsePacket(QByteArray &pkt)
{
    QBuffer bs(&pkt, this);
    if(!bs.open(QIODevice::ReadOnly))
    {
#ifdef EREMOTEPROTOCOL_QDEBUG
        qCritical()<<"打开数据流失败";
#endif
        return;
    }
    Server2ClientMessageType messageType;
    bs.read(static_cast<char*>(static_cast<void*>(&messageType)), sizeof(messageType));
    switch(messageType)
    {
    case S2C_CreateWindowEvent:
    {
        int wid, width, height, codec;
        bs.read(static_cast<char*>(static_cast<void*>(&wid)), sizeof(wid));
        bs.read(static_cast<char*>(static_cast<void*>(&width)), sizeof(width));
        bs.read(static_cast<char*>(static_cast<void*>(&height)), sizeof(height));
        bs.read(static_cast<char*>(static_cast<void*>(&codec)), sizeof(codec));
#ifdef EREMOTEPROTOCOL_QDEBUG
        qDebug()<<QString("创建窗口:%1 宽:%2 高:%3 编码:%4").arg(wid).arg(width).arg(height).arg(codec);
#endif
        emit receivedCreateWindow(wid, width, height, codec);
    }
        break;
    case S2C_UpdateWindowFramebufferEvent:
    {
        int wid;
        bs.read(static_cast<char*>(static_cast<void*>(&wid)), sizeof(wid));
        QByteArray data = bs.readAll();
#ifdef EREMOTEPROTOCOL_QDEBUG
        qDebug()<<QString("更新%1图像数据").arg(wid)<<data.size();
#endif
        emit receivedFramebuffer(wid, data);
    }
        break;
    case S2C_UpdateCutTextEvent:
    {
#ifdef EREMOTEPROTOCOL_QDEBUG
        qDebug()<<"更新剪切板";
#endif
        emit receivedCutText(QString::fromUtf8(bs.readAll()));
    }
        break;
    default:
#ifdef EREMOTEPROTOCOL_QDEBUG
        qWarning()<<"未知的消息类型:"<<static_cast<uint16_t>(messageType);
#endif
        break;
    }
}
